home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d8 / tlx315_2.arc / HOST.SLT < prev    next >
Text File  |  1991-04-02  |  29KB  |  1,087 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //   H O S T . S L T
  4. //
  5. //   Copyright (C) 1988,1989,1990,1991 Exis Inc.
  6. //
  7. //   - Written by Colin Sampaleanu.
  8. //   - Modifications by Jeff Woods, Feb '91, to add help function and support
  9. //     for locked modems.
  10. //
  11. //   This is a Host Mode for Telix, written as a script file.
  12. //   To configure Host Mode parameters such as passwords, run the 'HCONFIG'
  13. //   script. That script is run automatically if the Host Mode ocnfiguration
  14. //   file 'HOST.CNF' is missing.
  15. //
  16. //   This script will only work with Hayes compatible modems, but may be
  17. //   modified for operation with othe rmodems.
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20.  
  21. // Parameters which can be configured
  22.  
  23. str pass1[8] = "pass1",                 // The level 1 pass
  24.     pass2[8] = "pass2",                 // The level 2 (Sysop) pass
  25.     shellpass[8] = "shell",             // the pass to enter the Remote Shell
  26.     shutpass[8] = "shut",               // the pass to shut down the Host Mode
  27.     host_downloads[64],                 // where users may download from
  28.     host_uploads[64];                   // where uploaded files go
  29. int direct_connect = 0,
  30.     modem_lock = 0;
  31.  
  32. str current_caller[31],                 // storage of current caller's name
  33.     conn300[] = "CONNECT^M",            // modem result messages for bauds
  34.     conn1200[] = "CONNECT 1200",
  35.     conn2400[] = "CONNECT 2400",
  36.     conn9600[] = "CONNECT 9600",
  37.     conn19200[] = "CONNECT 19200";
  38.  
  39. int finished_caller,                    // set to TRUE when must return to top
  40.     local_mode,                         // set to TRUE when local test mode
  41.     access_level,                       // access level of current caller
  42.     carrier_counts = 1,                 // TRUE if should watch Carrier signal
  43.     already_connected = 0,
  44.     exit_requested = 0,                 // set to TRUE if Sysop has pressed Esc
  45.     connection_lost = 0,                // set to TRUE when carrier lost
  46.     kill_user = 0;                      // set to TRUE when user must be purged
  47.  
  48. int old_scr_chk_key,                    // storage for some system variables
  49.     old_cisb_auto,                      // which we have to modify and put
  50.     old_zmod_auto,                      // back to what they were when done
  51.     old_sound;
  52. str old_down_dir[64],
  53.     old_up_dir[64];
  54.  
  55. //////////////////////////////////////////////////////////////////////////////
  56. //////////////////////////////////////////////////////////////////////////////
  57.  
  58. main()
  59.  
  60. {
  61.  int c;
  62.  
  63.  clear_scr();
  64.  
  65.  if (read_host_config_file() == -1)
  66.   {
  67.    prints("Unable to read HOST.CNF...");
  68.    prints("Running HCONFIG, the Host Mode configuration script.^M^J");
  69.    call("HCONFIG");
  70.    if (read_host_config_file() == -1)
  71.     {
  72.      prints("Still unable to read HOST.CNF. Aborting Host Mode.^M^J");
  73.      return -1;
  74.     }
  75.   }
  76.  
  77.  if (!check_directories())
  78.   {
  79.    prints("Either the upload or download directory as defined in the HOST.CNF file");
  80.    prints("doesn't exist. Either create the missing directory with the DOS 'MKDIR'");
  81.    prints("command, or run the HCONFIG script to redefine what directories to use.");
  82.    prints("Aborting Host Mode.");
  83.    return -1;
  84.   }
  85.  
  86.  old_scr_chk_key = _scr_chk_key;
  87.  _scr_chk_key = 0;
  88.  old_cisb_auto = _cisb_auto;
  89.  _cisb_auto = 0;
  90.  old_zmod_auto = _zmod_auto;
  91.  _zmod_auto = 0;
  92.  old_sound = _sound_on;
  93.  _sound_on = 0;
  94.  old_down_dir = _down_dir;
  95.  _down_dir = host_uploads;   // these are reversed because we are now the Host
  96.  old_up_dir = _up_dir;
  97.  _up_dir = host_downloads;   // these are reversed because we are now the Host
  98.  
  99.  usagelog("HOST.LOG");
  100.  
  101.  if (direct_connect)
  102.   carrier_counts = 0;
  103.  else
  104.   carrier_counts = 1;
  105.  
  106.  if (!direct_connect && carrier())
  107.   already_connected = 1;
  108.  
  109.  
  110.  while (1)
  111.   {
  112.    if (!direct_connect && !already_connected)
  113.     {
  114.      if (!modem_lock)
  115.         set_cparams(modem_lock, 0, 8, 1);
  116.      delay(3);
  117.      prints("Sending Modem Init string...");
  118.      cputs_tr(_mdm_init_str);
  119.      delay(10);
  120.      prints("Sending Auto-Answer string...");
  121.      cputs_tr(_auto_ans_str);
  122.     }
  123.  
  124.    finished_caller = kill_user = 0;
  125.  
  126.    if (direct_connect)
  127.     carrier_counts = 0;
  128.    else
  129.     carrier_counts = 1;
  130.  
  131.    if (!direct_connect)
  132.     {
  133.      prints("^M^JHost Mode: Waiting for call...");
  134.      prints("(Press Esc to exit, or 'L' for local test mode).^M^J");
  135.  
  136.      do
  137.       {
  138.        if (carrier())
  139.         {
  140.          local_mode = 0;
  141.          break;
  142.         }
  143.  
  144.        c = inkey();
  145.        if (c)
  146.         {
  147.          if (c == 27)
  148.           {
  149.            exit_requested = 1;
  150.            break;
  151.           }
  152.          else if (c == 'l' || c == 'L')               // local teswt mode
  153.           {
  154.            prints("Local test mode entered");
  155.            local_mode = 1;
  156.            carrier_counts = 0;
  157.           }
  158.         }
  159.       }
  160.      while (toupper(c) != 'L');
  161.     }
  162.  
  163.    if (!exit_requested)
  164.     {
  165.      prints("Incoming call. Sysop: press Esc to exit, or END to terminate user.");
  166.  
  167.      do_one_caller();
  168.      if ((connection_lost || kill_user) && carrier_counts && carrier())
  169.       hangup();             // make sure nobody sneaks in
  170.     }
  171.    already_connected = 0;
  172.    if (exit_requested)
  173.     {
  174.      if (!carrier() && !direct_connect)
  175.       {
  176.        prints("Sending Modem Init string...");
  177.        cputs_tr(_mdm_init_str);
  178.       }
  179.      _scr_chk_key = old_scr_chk_key;
  180.      _cisb_auto = old_cisb_auto;
  181.      _zmod_auto = old_zmod_auto;
  182.      _sound_on = old_sound;
  183.      _down_dir = old_down_dir;
  184.      _up_dir = old_up_dir;
  185.      prints("^M^JHost mode script finished.");
  186.      usagelog("*CLOSE*");
  187.      return 1;
  188.     }
  189.   }
  190. }
  191.  
  192. //////////////////////////////////////////////////////////////////////////////
  193.  
  194. HelpOn(int option)
  195.  
  196. {
  197.    if (option == 'H')
  198.     {
  199.      host_send("^M^JHelp on Help^M^J");
  200.      Host_send("^M^JTo use the help, simply type the first letter of one of the following:");     host_send("^M^J^M^J<H>elp <F>iles <T>ype <U>pload <D>ownload <S>hell <C>hat <G>oodbye ");
  201.      host_send("^M^J^M^J<H>elp <F>iles <T>ype <U>pload <D>ownload <S>hell <C>hat <G>oodbye");
  202.      Host_send("^M^J");
  203.     }
  204.    if (option == 'F')
  205.     {
  206.      host_send("^M^JHelp on Files^M^J");
  207.      host_send("^M^JThe 'Files' option allows the caller to list the files in the");
  208.      host_send("^M^Jcurrent disk directory. The caller must press a key after each");
  209.      host_send("^M^Jscreen. The output is not echoed on the local screen. If the");
  210.      host_send("^M^Jcaller has access level two s/he is prompted for a filespec,");
  211.      host_send("^M^Jwhich may include the * and ? wildcard characters (see your");
  212.      host_send("^M^JDOS manual), so that the contents of other directories than");
  213.      host_send("^M^Jthe 'Host download dir' may be listed.");
  214.      Host_send("^M^J");
  215.     }
  216.    if (option == 'T')
  217.     {
  218.      host_send("^M^JHelp on Type^M^J");
  219.      host_send("^M^JThe 'Type' option allows the caller to view any ASCII file in");
  220.      host_send("^M^Jthe Host Download Directory, or in any directory for access");
  221.      host_send("^M^JLevel 2 callers.   Simply give the name (or full path and name)");
  222.      host_send("^M^Jof the system file you wish to view:    ie. C:\TELIX\TELIX.IMG");
  223.      Host_send("^M^J");
  224.     }
  225.    if (option == 'U')
  226.     {
  227.      host_send("^M^JHelp on Uploading^M^J");
  228.      host_send("^M^JThe 'Upload' option allows the caller to send a file to the");
  229.      host_send("^M^Jhost. The caller is shown the a menu of protocols.   He/she");
  230.      host_send("^M^Jshould select the appropriate protocol by its first letter");
  231.      host_send("^M^J(or 'E' for Ymodem-g). If appropriate the caller is also asked");
  232.      host_send("^M^Jfor the filename.  The transfer is then initiated by HOST.  The");
  233.      host_send("^M^Jcaller must then initiate the upload on THEIR side by giving");
  234.      host_send("^M^Jtheir comm program an upload instruction, choosing the same");
  235.      host_send("^M^Jprotocol as they told host, and giving the filename again,");
  236.      host_send("^M^Jwithin 60 seconds of telling HOST the same information.");
  237.      Host_send("^M^J");
  238.     }
  239.    if (option == 'D')
  240.     {
  241.      host_send("^M^JHelp on Downloading^M^J");
  242.      host_send("^M^JThe 'Download' command allows a caller to receive a file from");
  243.      host_send("^M^Jthe host. The caller must select the protocol after giving the");
  244.      host_send("^M^Jdownload commadn to HOST, and then must tell HOST what files");
  245.      host_send("^M^Jto send.    Some protocols like ZModem will start automatically");
  246.      host_send("^M^Jafter this.   Others, like XModem, require the caller to start");
  247.      host_send("^M^Ja download in their comm program at this point (usually Pg-Dn)");
  248.      host_send("^M^Jand will be asked by the comm program for a file name again.  The");
  249.      host_send("^M^Jtransfer is then initiated.");
  250.      Host_send("^M^J");
  251.     }
  252.    if (option == 'S')
  253.     {
  254.      host_send("^M^JHelp on Shelling^M^J");
  255.      host_send("^M^JThe 'Shell' command is a very powerful but also very dangerous");
  256.      host_send("^M^Jcommand. It allows the caller to run a DOS shell on the sys-");
  257.      host_send("^M^Jtem, except that the caller receives the output, and the");
  258.      host_send("^M^Jcaller enters the keystrokes.   The caller has complete control");
  259.      host_send("^M^Jof the HOST system at the DOS level.   Shell is a password");
  260.      host_send("^M^Jprotected feature of HOST.  The caller sees program output only");
  261.      host_send("^M^Jif the programs use standard DOS output. Programs that write");
  262.      host_send("^M^Jdirectly to the video screen will work, but will not be seen");
  263.      host_send("^M^Jby the remote caller. As well, programs that use non-DOS meth-");
  264.      host_send("^M^Jods of getting keystrokes will not receive the callers");
  265.      host_send("^M^Jkeystrokes. Finally, under some systems, if the caller presses");
  266.      host_send("^M^JBackspace at the DOS prompt when the current line is empty,");
  267.      host_send("^M^JDOS will hang on the Host machine. As these are functions of");
  268.      host_send("^M^JDOS, there is nothing that can be done about these limits.");
  269.      Host_send("^M^J");
  270.     }
  271.    if (option == 'C')
  272.     {
  273.      host_send("^M^JHelp on Chatting^M^J");
  274.      host_send("^M^JThe 'Chat' command allows the caller to chat with the host op-");
  275.      host_send("^M^Jerator. When the caller presses 'C' the host operator is paged");
  276.      host_send("^M^Jfor 20 seconds.    If the host operator responds, you will see");
  277.      host_send("^M^Jhim/her typing on your screen.    If you can, place yourself in");
  278.      host_send("^M^JChat Mode, by using your comm program's chat mode (Telix's is");
  279.      host_send("^M^JAlt-Y).   You will then see what you type on half of the screen");
  280.      host_send("^M^Jand the operator's words on the other half.");
  281.      Host_send("^M^J");
  282.     }
  283.    if (option == 'G')
  284.     {
  285.      host_send("^M^JHelp on Goodbye^M^J");
  286.      host_send("^M^JThe 'Goodbye' command allows the caller to log off the host");
  287.      Host_send("^M^J");
  288.     }
  289. }
  290.  
  291. //////////////////////////////////////////////////////////////////////////////
  292.  
  293. do_one_caller()
  294.  
  295. {
  296.  str strn[80],
  297.      fname[64];
  298.  int option,
  299.      status,
  300.      c, i, i2, f;
  301.  
  302.  access_level = 1;
  303.  
  304.  if (already_connected)
  305.   prints("Already connected, or modem Carrier Detect switch improperly set!");
  306.  else if (carrier_counts)
  307.   {
  308.    if (!modem_lock)
  309.     if (!determine_baud())
  310.     ;                          // do something else here if this is a problem
  311.   }
  312.  
  313.  delay(10);
  314.  type_file("LOGO.MSG");
  315.  
  316.  flushbuf();
  317.  while (1)
  318.   {
  319.    host_send("Please enter your full name: ");
  320.    host_input_strn(current_caller, 30, 1);
  321.    host_send("^M^J");
  322.  
  323.    if (finished_caller)
  324.     return;
  325.  
  326.    if (strlen(current_caller) >= 5)
  327.     break;
  328.   }
  329.  
  330.  access_level = ask_for_pass(3, pass1, pass2);
  331.  
  332.  if (access_level)
  333.   ustamp("Logon by ", 1, 0);
  334.  else
  335.   ustamp("Failed logon attempt by ", 1, 0);
  336.  ustamp(current_caller, 0, 1);
  337.  
  338.  if (!access_level)
  339.   {
  340.    host_send("Goodbye!^M^J");
  341.    if (carrier_counts)
  342.     {
  343.      delay(10);
  344.      hangup();
  345.     }
  346.    return;
  347.   }
  348.  
  349.  type_file("WELCOME.MSG");
  350.  
  351.  while (1)
  352.   {
  353.    if (finished_caller)
  354.     return;
  355.  
  356.    host_send("^M^JCommand: Help  Files  Type  Upload  Download  Shell  Chat  Goodbye ? ");
  357.    host_input_strn(strn, 1, 1);
  358.    option = toupper(subchr(strn, 0));
  359.    host_send("^M^J");
  360.  
  361.    if (option == 'H')
  362.     {
  363.      host_send("^M^J^M^JWhich item above do you wish help on? ");
  364.      host_input_strn(strn, 1, 1);
  365.      Option = toupper(subchr(strn, 0));
  366.      Host_send("^M^J");
  367.      HelpOn(Option);
  368.      Option = 'H';
  369.     }
  370.    if (option == 'F')                 // Files directory
  371.     {
  372.      if (access_level == 2)
  373.       {
  374.        host_send("Enter 'filespec' or press Return for *.*,^M^J: ");
  375.        host_input_strn(fname, 64, 1);
  376.        host_send("^M^J");
  377.  
  378.        if (just_filename(fname))
  379.         {
  380.          strn = host_downloads;
  381.          strcat(strn, fname);
  382.         }
  383.        else
  384.         strn = fname;
  385.       }
  386.      else
  387.       {
  388.        strn = host_downloads;
  389.        strcat(strn, "*.*");
  390.       }
  391.        
  392.      if (local_mode)
  393.       show_directory(strn, 0, carrier_counts);
  394.      else
  395.       show_directory(strn, 1, carrier_counts);
  396.      host_send("^M^J");
  397.     }
  398.    else if (option == 'T')            // Type a file
  399.     {
  400.      host_send("Type what file? ");
  401.      host_input_strn(strn, 64, 1);
  402.      host_send("^M^J");
  403.      if (access_level != 2)             // if access 1, name and ext only
  404.       fnstrip(strn, 3, fname);
  405.      else
  406.       fname = strn;
  407.  
  408.      if (just_filename(fname))
  409.       {
  410.        strn = host_downloads;
  411.        strcat(strn, fname);
  412.        fname = strn;
  413.       }
  414.  
  415.      if (!filefind(fname, 0, strn))
  416.       {
  417.        host_send("Unable to find ");
  418.        host_send(fname);
  419.        continue;
  420.       }
  421.  
  422.      type_file(fname);
  423.     }
  424.    else if (option == 'G')            // Goodbye (Hang-up)
  425.     {
  426.      host_send("^M^JGoodbye!^M^J");
  427.      ustamp("User logged off.", 1, 1);
  428.      if (carrier_counts)
  429.       {
  430.        delay(10);
  431.        hangup();
  432.       }
  433.      return;
  434.     }
  435.    else if (option == 'C')            // Chat mode
  436.     {
  437.      prints("Sysop: Press Space to chat, any other key not to.^M^J");
  438.      c = 0;
  439.      _sound_on = 1;
  440.      for (i = 8; i && !c; --i)
  441.       {
  442.        if (carrier_counts && !carrier())
  443.         {
  444.          prints("^M^JConnection has been lost, call terminated.^M^J");
  445.          connection_lost = 1;
  446.          finished_caller = 1;
  447.          break;
  448.         }
  449.        cputc('^G');
  450.        tone(523, 20);
  451.        tone(659, 20);
  452.        tone(523, 20);
  453.        tone(659, 20);
  454.        tone(523, 20);
  455.        tone(659, 20);
  456.        for (i2 = 30; i2 && (c = inkey()) == 0; --i2)
  457.         delay(1);
  458.       }
  459.      _sound_on = 0;
  460.      if (finished_caller)
  461.       continue;
  462.      if (c != ' ' || !c)
  463.       {
  464.        host_send("Sorry, the Sysop is unavailable^M^J");
  465.        continue;
  466.       }
  467.      host_send("The sysop is here!^M^J");
  468.      chatmode(1);
  469.     }
  470.    else if (option == 'U')            // User upload
  471.     {
  472.      option = host_get_prot();
  473.      if (!option)
  474.       continue;
  475.  
  476.      status = 1;
  477.      if (option == 'T' || option == 'M' || option == 'S' ||
  478.          option == 'Y' || option == 'Z' || option == 'E')
  479.       {
  480.        send_transfer_msg();
  481.        status = receive(option, "");
  482.       }
  483.      else
  484.       {
  485.        host_send("Upload what file? ");
  486.        host_input_strn(strn, 48, 1);
  487.        host_send("^M^J");
  488.        if (!strn)
  489.         continue;
  490.        if (access_level != 2)             // if access 1, name and ext only
  491.         fnstrip(strn, 3, fname);
  492.        else
  493.         fname = strn;
  494.  
  495.        if (just_filename(fname))
  496.         {
  497.          strn = host_uploads;
  498.          strcat(strn, fname);
  499.          fname = strn;
  500.         }
  501.  
  502.        if (filefind(fname, 23, strn))
  503.         host_send("File already exists!^M^J");
  504.        else
  505.         {
  506.          send_transfer_msg();
  507.          status = receive(option, fname);
  508.         }
  509.       }
  510.      if (status == -2)                        // Carrier lost
  511.       connection_lost = finished_caller = 1;
  512.      else if (status == -1)
  513.       host_send("^GOne or more files not received!^M^J");
  514.     }
  515.    else if (option == 'D')            // User download
  516.     {
  517.      option = host_get_prot();
  518.      if (!option)
  519.       continue;
  520.      host_send("Download what file(s)? ");
  521.      host_input_strn(strn, 48, 1);
  522.      host_send("^M^J");
  523.      if (!strn)
  524.       continue;
  525.      if (access_level != 2)      // if not level 2, keep only name & ext
  526.       fnstrip(strn, 3, fname);
  527.      else
  528.       fname = strn;
  529.  
  530.      if (just_filename(fname))
  531.       {
  532.        strn = host_downloads;
  533.        strcat(strn, fname);
  534.        fname = strn;
  535.       }
  536.  
  537.      if (!filefind(fname, 0, strn))
  538.       {
  539.        host_send("Unable to find any matching file(s)!^M^J");
  540.        continue;
  541.       }
  542.  
  543.      status = 1;
  544.      send_transfer_msg();
  545.      status = send(option, fname);
  546.      if (status == -2)                        // Carrier lost
  547.       connection_lost = finished_caller = 1;
  548.      else if (status == -1)
  549.       host_send("^GOne or more files not received!^M^J");
  550.     }
  551.    else if (option == 'S')            // Remote shell
  552.     {
  553.      if (ask_for_pass(3, shellpass, shellpass) != 0)
  554.       {
  555.        host_send("Type EXIT and then press Enter to come back.^M^J");
  556.        if (get_baud() == 300)
  557.         delay(10);
  558.        if (local_mode)
  559.         dos("", 0);
  560.                  // See if user has prepared a custom file for shell operation
  561.                  // and call that if it exists
  562.        else if (filefind("RSHELL.BAT", 0, strn))
  563.         dos("RSHELL.BAT", 0);
  564.        else   // otherwise make our own temporary batch file for redirection
  565.         {
  566.          // now want to make a temporary batch file which will be called
  567.          // to redirect DOS input and output, then shell to another copy
  568.          // of COMMAND.COM
  569.          f = fopen("HOSTTEMP.BAT", "w");
  570.          if (f)
  571.           {
  572.            if (get_port() != 1 && get_port() != 2)
  573.             {
  574.              host_send("Remote Shell not supported on this comm port due to DOS limits!^M^J");
  575.              continue;
  576.             }
  577.  
  578.            strn = "COMx";
  579.            setchr(strn, 3, get_port() + '0'); // get right name to redirect
  580.  
  581.            fputs("CTTY ", f);           // write to batch file
  582.            fputs(strn, f);
  583.            fputs("^M^JCOMMAND^M^J", f);
  584.            fputs("CTTY CON^M^J", f);
  585.            fputs("EXIT^M^J", f);
  586.  
  587.            fclose(f);                   // close the file
  588.  
  589.            if (!local_mode)             // call batch file
  590.             dos("HOSTTEMP.BAT", 0);
  591.           }
  592.          else
  593.           host_send("Can't open temporary batch file!^M^J");
  594.         }
  595.       }
  596.     }
  597.    else if (option == '^Z')            // Shut down Host Mode
  598.     {
  599.      host_send("Shut down Host mode. ");
  600.      if (!ask_for_pass(3, shutpass, shutpass))
  601.       continue;
  602.      host_send("Goodbye!^M^J");
  603.      if (carrier_counts)
  604.       hangup();
  605.      ustamp("User shut down Host Mode.", 1, 1);
  606.      finished_caller = 1;
  607.      exit_requested = 1;
  608.     }
  609.   }
  610. }
  611.  
  612. //////////////////////////////////////////////////////////////////////////////
  613.  
  614. host_get_prot()
  615.  
  616. {
  617.  str prot[1];
  618.  
  619.  host_send("^M^JModem7  SEAlink  Xmodem  1k-Xmodem  G-1k-Xmodem  Ymodem  YmodEm-g  Zmodem^M^J");
  620.  host_send("Which protocol? ");
  621.  host_input_strn(prot, 1, 1);
  622.  host_send("^M^J");
  623.  
  624.  if (strposi("MSX1GYEZ", prot, 0) == -1)     // if illegal prot
  625.   prot = "";                                 // return 0
  626.  
  627.  return (toupper(subchr(prot, 0)));
  628.  
  629. }
  630.  
  631. //////////////////////////////////////////////////////////////////////////////
  632.  
  633. send_transfer_msg()
  634.  
  635. {
  636.  host_send("Ready to transfer file(s)... Press Ctrl-X at least twice to abort^M^J");
  637. }
  638.  
  639. //////////////////////////////////////////////////////////////////////////////
  640. // Determine the baud rate once a Carrier Detect Signal has been detected
  641. // Since no characters were read, the 'CONNECT' string should still be
  642. // in the receive buffer.
  643.  
  644. determine_baud()
  645.  
  646. {
  647.  int t3, t12, t24, t96, t192;
  648.  int tmark, stat;
  649.  int new_baud = 0;
  650.  
  651.  printsc("Determining baud... ");
  652.  
  653.  track_free(0);                // clear all existing tracks
  654.  
  655.  t3 = track(conn300, 0);       // check for connect strings
  656.  t12 = track(conn1200, 0);
  657.  t24 = track(conn2400, 0);
  658.  t96 = track(conn9600, 0);
  659.  t192 = track(conn19200, 0);
  660.  
  661.  tmark = timer_start(30);      // wait up to 3 seconds for string
  662.                              
  663.  while (!time_up(tmark))
  664.   {
  665.    if (!carrier())
  666.     {
  667.      track_free(0);            // clear all existing tracks
  668.      return 0;
  669.     }
  670.  
  671.    if (cinp_cnt())
  672.     track_addchr(cgetc());
  673.  
  674.    stat = track_hit(0);
  675.    if (stat == 0)
  676.     continue;
  677.  
  678.    if (stat == t3)
  679.     new_baud = 300;
  680.    else if (stat == t24)
  681.     new_baud = 2400;
  682.    else if (stat == t96)
  683.     new_baud = 9600;
  684.    else if (stat == t192)
  685.     new_baud = 19200;
  686.    else
  687.     new_baud = 1200;
  688.  
  689.    break;                      // have baud rate, get out
  690.   }
  691.  
  692.  if (!new_baud)                // time-up without CONNECT string
  693.   {
  694.    prints("Failed!");
  695.    track_free(0);              // clear all existing tracks
  696.    return 0;     
  697.   }
  698.  
  699.  printn(new_baud);
  700.  prints("");
  701.  set_cparams(new_baud, get_parity(), get_datab(), get_stopb());
  702.  
  703.  track_free(0);                // clear all existing tracks
  704.  return 1;                     // indicate success
  705.  
  706. }
  707.  
  708. //////////////////////////////////////////////////////////////////////////////
  709.  
  710. type_file(str fname)
  711.  
  712. {
  713.  int f;
  714.  str buf[100];
  715.  int ichar, lines_sent = 0;
  716.  
  717.  f = fopen(fname, "r");
  718.  if (!f)
  719.   return -1;
  720.  
  721.  host_send("^M^J");
  722.  
  723.  while (1)
  724.   {
  725.    if (carrier_counts)
  726.     if (!carrier())
  727.      {
  728.       connection_lost = 1;
  729.       finished_caller = 1;
  730.       fclose(f);
  731.       return 0;
  732.      }
  733.  
  734.    if (fgets(buf, 80, f) == -1)
  735.     {
  736.      fclose(f);
  737.      return 1;
  738.     }
  739.  
  740.    host_send(buf);
  741.    host_send("^M^J");
  742.    ++lines_sent;
  743.  
  744.    if (lines_sent >= 22)
  745.     {
  746.      lines_sent = 0;
  747.      host_send("[More]");
  748.      host_input(1);
  749.  
  750.      if (finished_caller)         // if user inactivity
  751.       {
  752.        fclose(f);
  753.        return 0;
  754.       }
  755.  
  756.      host_send("^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H");
  757.     }
  758.  
  759.    while (cinp_cnt())
  760.     {
  761.      ichar = cgetc();
  762.      if (ichar == '^C' || ichar == '^K')
  763.       {
  764.        host_send("^M^J");
  765.        fclose(f);
  766.        return 1;
  767.       }
  768.     }
  769.   }
  770. }
  771.  
  772. //////////////////////////////////////////////////////////////////////////////
  773.  
  774. host_send(str outstr)
  775.  
  776. {
  777.  
  778.  printsc(outstr);
  779.  if (!local_mode)
  780.   cputs(outstr);
  781.  
  782. }
  783.  
  784. //////////////////////////////////////////////////////////////////////////////
  785.  
  786. host_send_c(int chr)
  787.  
  788. {
  789.  
  790.  printc(chr);
  791.  if (!local_mode)
  792.   cputc(chr);
  793.  
  794. }
  795.  
  796. //////////////////////////////////////////////////////////////////////////////
  797.  
  798. host_input_strn(str buf, int maximum, int echoable)
  799.  
  800. {
  801.  int i = 0, key;
  802.  
  803.  while (1)
  804.   {
  805.    key = host_input(echoable);
  806.    if (!key)                 // timeout or user disconnect
  807.     {
  808.      setchr(buf, 0, 0);      // set string to empty
  809.      return 0;               // indicate there is a problem
  810.     }
  811.  
  812.    if (key == '^M')
  813.     break;
  814.    if (key == 127 || key == 8)
  815.     {
  816.      if (i)
  817.       {
  818.        --i;
  819.          host_send_c(key);
  820.       }
  821.      continue;
  822.     }
  823.    if (i < maximum)
  824.     {
  825.      setchr(buf, i, key);
  826.      i = i + 1;
  827.     }
  828.    else
  829.     i = i + 1;
  830.   }
  831.  
  832.  if (i > maximum)
  833.   i = maximum;
  834.  
  835.  setchr(buf, i, '^0');
  836.  
  837.  if (subchr(buf, 0))
  838.   return 1;
  839.  else
  840.   return 0;
  841.  
  842. }
  843.  
  844. //////////////////////////////////////////////////////////////////////////////
  845.  
  846. host_input(int echoable)
  847.  
  848. {
  849.  int c;
  850.  int t;
  851.  
  852.  t = timer_start(2400);         // 4 minutes inactivity allowed
  853.  
  854.  while (1)
  855.   {
  856.    if (time_up(t) && !direct_connect)
  857.     {
  858.      host_send("^M^J^M^JInactivity period too long. Connection terminated!^M^J");
  859.      if (carrier_counts)
  860.       hangup();
  861.      finished_caller = 1;
  862.      kill_user = 1;
  863.      return 0;
  864.     }
  865.  
  866.    if (carrier_counts)
  867.     if (!carrier())
  868.       {
  869.        prints("^M^JConnection has been lost, call terminated.^M^J");
  870.        connection_lost = 1;
  871.        finished_caller = 1;
  872.        return 0;
  873.       }
  874.  
  875.    if ((c = inkey()) != 0)
  876.     {
  877.      if (c == 27)               // ESC key, sysop wants to exit
  878.       {
  879.        finished_caller = 1;
  880.        exit_requested = 1;
  881.        return 0;
  882.       }
  883.      else if (c == 0x4f00)      // END key, temrinate user
  884.       {
  885.        prints("^M^JUser terminated!");
  886.        ustamp("User terminated!", 1, 1);
  887.        if (carrier_counts)
  888.         hangup();
  889.  
  890.        finished_caller = 1;
  891.        kill_user = 1;
  892.        return 0;
  893.       }
  894.  
  895.      else if (c <= 255)
  896.       {
  897.        if (c != 8 && c != 127)   
  898.         if (!echoable)
  899.          host_send_c('*');
  900.         else
  901.          host_send_c(c);
  902.        return c;
  903.       }
  904.     }
  905.  
  906.    if (!local_mode)
  907.     if (cinp_cnt())
  908.      {
  909.       c = cgetc();
  910.       if (c != 8 && c != 127)
  911.        if (!echoable)
  912.         host_send_c('*');
  913.        else
  914.         host_send_c(c);
  915.       return c;
  916.      }
  917.   }
  918. }
  919.  
  920. //////////////////////////////////////////////////////////////////////////////
  921.  
  922. ask_for_pass(int maxtries, str pass1, str pass2)
  923.  
  924. {
  925.  int i;
  926.  str strn[8];
  927.  
  928.  for (i = 0; i < maxtries; ++i)
  929.   {
  930.    if (i)
  931.     host_send("Wrong! Try again.^M^J");
  932.    host_send("Password: ");
  933.    host_input_strn(strn, 8, 0);
  934.    host_send("^M^J");
  935.  
  936.    if (finished_caller)
  937.     return 0;
  938.  
  939.    if (!strcmpi(strn, pass1))
  940.     return 1;
  941.  
  942.    if (!strcmpi(strn, pass2))
  943.     return 2;
  944.   }
  945.  
  946.  host_send("No more chances. Access denied.^M^J");
  947.  
  948.  return 0;
  949.  
  950. }
  951.  
  952. //////////////////////////////////////////////////////////////////////////////
  953.  
  954. read_host_config_file()
  955.  
  956. {
  957.  str s[80];
  958.  int f, stat;
  959.  
  960.  s = _telix_dir;
  961.  strcat(s, "HOST.CNF");
  962.  
  963.  f = fopen(s, "r");
  964.  if (!f)
  965.   {
  966.    printsc("Can't open ");
  967.    prints(s);
  968.    return -1;
  969.   }
  970.  
  971.  stat = fgets(s, 80, f);
  972.  if (stat == -1)
  973.   goto got_error;
  974.  pass1 = s;
  975.  
  976.  stat = fgets(s, 80, f);
  977.  if (stat == -1)
  978.   goto got_error;
  979.  pass2 = s;
  980.  
  981.  stat = fgets(s, 80, f);
  982.  if (stat == -1)
  983.   goto got_error;
  984.  shellpass = s;
  985.  
  986.  stat = fgets(s, 80, f);
  987.  if (stat == -1)
  988.   goto got_error;
  989.  shutpass = s;
  990.  
  991.  stat = fgets(s, 80, f);
  992.  if (stat == -1)
  993.   goto got_error;
  994.  host_downloads = s;
  995.  
  996.  stat = fgets(s, 80, f);
  997.  if (stat == -1)
  998.   goto got_error;
  999.  host_uploads = s;
  1000.  
  1001.  stat = fgets(s, 80, f);
  1002.  if (stat == -1)
  1003.   goto got_error;
  1004.  direct_connect = (toupper(subchr(s, 0)) == 'D');
  1005.  
  1006.  stat = fgets(s, 80, f);
  1007.  if (stat == -1)
  1008.   goto got_error;
  1009.  modem_lock = stoi(s);
  1010.  
  1011.  fclose(f);
  1012.  return 1;
  1013.  
  1014. // jump here if error
  1015.  
  1016.  got_error:
  1017.   fclose(f);
  1018.   return -1;
  1019.  
  1020. }
  1021.  
  1022. //////////////////////////////////////////////////////////////////////////////
  1023.  
  1024. check_directories()
  1025.  
  1026. {
  1027.  str s[80];
  1028.  int i, a;
  1029.  
  1030.  // first remove trailing slashes
  1031.  
  1032.  s = host_uploads;
  1033.  i = strlen(s);
  1034.  if (i > 0)
  1035.   if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1036.    setchr(s, i - 1, 0);
  1037.  if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
  1038.   {
  1039.    a = fileattr(s);
  1040.    if (a == -1 || !(a & 16))
  1041.     return 0;                  // not a directory or doesn't exist
  1042.   }
  1043.  
  1044.  s = host_downloads;
  1045.  i = strlen(s);
  1046.  if (i > 0)
  1047.   if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
  1048.    setchr(s, i - 1, 0);
  1049.  if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
  1050.   {
  1051.    a = fileattr(s);
  1052.    if (a == -1 || !(a & 16))
  1053.     return 0;                  // not a directory or doesn't exist
  1054.   }
  1055.  
  1056.  return 1;
  1057.  
  1058. }
  1059.  
  1060. //////////////////////////////////////////////////////////////////////////////
  1061. // returns TRUE if passed filespec is just a filename. Also handles the
  1062. // forward slash as a path separator.
  1063.  
  1064. just_filename(str filespec)
  1065.  
  1066. {
  1067.  int slash, space;
  1068.  
  1069.  if (strpos(filespec, ":", 0) != -1)
  1070.   return 0;
  1071.  if (strpos(filespec, "\", 0) != -1)
  1072.   return 0;
  1073.  if ((slash = strpos(filespec, "/")) == -1)
  1074.   return 1;
  1075.  
  1076.  space = strpos(filespec, " ");
  1077.  if (space == -1)
  1078.   return 0;
  1079.  if (space < slash)
  1080.   return 1;
  1081.  
  1082.  return 0;
  1083.  
  1084. }
  1085.  
  1086. //////////////////////////////////////////////////////////////////////////////
  1087.